<?php

/**
 *Simple CRUD Code Generator
 *Email:  support@crazedcoders.com
 *Website: http://www.crazedcoders.com/
 *Copyright (C) 2007 CrazedCoders
 *
 *This program is free software: you can redistribute it and/or modify
 *it under the terms of the GNU General Public License as published by
 *the Free Software Foundation, either version 3 of the License, or
 *(at your option) any later version.
 *
 *THE PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *SOFTWARE.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * generateds a Cairngorm command for a given table
 */
function generateCommandForTable( $columns ) {
	$table = $columns;
	$className = toCamelCase( $columns[0][2]['table_name'] );
	$classNameUp = strtoupper( $className );
	$tableName = $columns[0][2]['table_name'];
	$primaryKey =  getPKey( $columns );
		//toCamelCaseMember($columns[0]['column_name']);
	$refManyTables = findRefManyColumnsFromTable( $columns );

	# create the require_once path
	$requireOnceVoPath = "";


	$export =
'package '.con::$package.'.command
{

	/**
	 *Simple CRUD Code Generator
	 *Email:  support@crazedcoders.com
	 *Website: http://www.crazedcoders.com/
	 *Copyright (C) 2007 CrazedCoders
	 *
	 *This program is free software: you can redistribute it and/or modify
	 *it under the terms of the GNU General Public License as published by
	 *the Free Software Foundation, either version 3 of the License, or
	 *(at your option) any later version.
	 *
	 *THE PROGRAM IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
	 *SOFTWARE.
	 *
	 *You should have received a copy of the GNU General Public License
	 *along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */

	import com.adobe.cairngorm.control.CairngormEvent;
	import com.adobe.cairngorm.control.CairngormEventDispatcher;
	import com.adobe.cairngorm.commands.ICommand;
	import mx.controls.Alert;
	import com.adobe.cairngorm.business.ServiceLocator;
	import mx.rpc.AsyncToken;
	import mx.collections.ArrayCollection;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.events.FaultEvent;
	import flash.events.Event;
	import mx.rpc.remoting.RemoteObject;
	import mx.utils.ArrayUtil;
	import '.con::$package.'.event.'.$className.'Event;
	import '.con::$package.'.model.AppModel;
	import com.adobe.cairngorm.model.ModelLocator;
	import mx.rpc.IResponder;
	import com.crazedcoders.lib.interfaces.IView;
	import '.con::$package.'.vo.'.$className.';


	public class '.$className.'Command implements ICommand, IResponder
	{
		private var _model:AppModel = AppModel.getInstance();

		public function '.$className.'Command(){
			super();
		}

		public function execute(event:CairngormEvent):void
		{
			//here you would issue commands based on the eventType
			// we interogate the type because
			// Commands can support multiple events if you so choose
			var service:RemoteObject = ServiceLocator.getInstance()
					.getRemoteObject("'.$className.'DaoRo");
			var token:AsyncToken;
			var clone:'.$className.';
			switch(event.type)
			{
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_COUNT_ALL:
					token = service.countAll();
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ALL:
					token = service.getAll();
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ALL_BY_START_LENGTH:
					token = service.getAllByStartLength(
						'.$className.'Event(event).paramStart,
						'.$className.'Event(event).paramLength);
					break;
';
	if( ! array_key_exists('isManyToMany', $table )
			|| ! $table['isManyToMany'] ) {
		$export .=

'
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_UPDATE_ONE:
					clone = '.$className.'Event(event).paramItem.store();
					token = service.updateOne( clone );
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ONE:
					token = service.getOne(
						'.$className.'Event(event).paramPrimaryKey );
					break;
';
	}
	else {
		$bothEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[0][2]['column_name']).'_'.
			strtoupper($table[1][2]['column_name']);
		$firstEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[0][2]['column_name']);
		$secondEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[1][2]['column_name']);
		$bothMethod = 'getAllBy_'.
			toCamelCaseMember($table[0][2]['column_name']).'_'.
			toCamelCaseMember($table[1][2]['column_name']);
		$firstMethod = 'getAllBy_'.
			toCamelCaseMember($table[0][2]['column_name']);
		$secondMethod = 'getAllBy_'.
			toCamelCaseMember($table[1][2]['column_name']);
		$export .=
'
				//defines the event constant in the event object
				case '.$className.'Event.'.$bothEvent.':
					token = service.'.$bothMethod.'.apply(service,
							'.$className.'Event(event).paramsMapping );
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$firstEvent.':
					token = service.'.$firstMethod.'.apply(service,
							'.$className.'Event(event).paramsMapping );
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$secondEvent.':
					token = service.'.$secondEvent.'.apply(service,
							'.$className.'Event(event).paramsMapping );
					break;
';
	}
	$export .=
'
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_DELETE_ONE:
					clone = '.$className.'Event(event).paramItem.store();
					token = service.deleteOne( clone );
					break;
				//defines the event constant in the event object
				case '.$className.'Event.'.$classNameUp.'_ACTION_CREATE_ONE:
					clone = '.$className.'Event(event).paramItem.store();
					token = service.createOne( clone );
					break;
				//include "'.$className.'_execinclude.as";
			}
			token.addResponder( this );
			//attach original event to token
			token.originator = event;
		}


		public function fault( info:Object ):void {
			// do nothing for now
			Alert.show(FaultEvent(info).fault.message);
		}

		public function result( data:Object ):void {
			var event:ResultEvent = ResultEvent( data );
			var orgEv:'.$className.'Event = event.token.originator;
			switch( orgEv.type ) {
				case '.$className.'Event.'.$classNameUp.'_ACTION_COUNT_ALL:
					this.onCountAll( event );
					break;
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ALL:
					this.onGetAll( event );
					break;
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ALL_BY_START_LENGTH:
					this.onGetAllByStartLength( event );
					break;
				case '.$className.'Event.'.$classNameUp.'_ACTION_CREATE_ONE:
					this.onCreateOne( event );
					break;
				case '.$className.'Event.'.$classNameUp.'_ACTION_DELETE_ONE:
					this.onDeleteOne( event );
					break;
';
	if( ! array_key_exists('isManyToMany', $table )
			|| ! $table['isManyToMany'] ) {
		$export .=

'
				case '.$className.'Event.'.$classNameUp.'_ACTION_UPDATE_ONE:
					this.onUpdateOne( event );
					break;
				case '.$className.'Event.'.$classNameUp.'_ACTION_GET_ONE:
					this.onGetOne( event );
					break;
';
	}
	else {
		$bothEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[0][2]['column_name']).'_'.
			strtoupper($table[1][2]['column_name']);
		$firstEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[0][2]['column_name']);
		$secondEvent = $classNameUp.'_ACTION_GET_ALL_BY_'.
			strtoupper($table[1][2]['column_name']);
		$export .=

'
				case '.$className.'Event.'.$bothEvent.':
					this.onGetAll( event );
					break;
				case '.$className.'Event.'.$firstEvent.':
					this.onGetAll( event );
					break;
				case '.$className.'Event.'.$secondEvent.':
					this.onGetAll( event );
					break;
';
	}
		$export .=
'
				//include "'.$className.'_resultinclude.as";
			}
		}
		//include "'.$className.'_include.as";


		public static function addObjectsToModel( inArr:Array ):void {
			if( inArr == null ||  inArr[0] == null )
				return;
			var _model:AppModel = AppModel.getInstance();
			for( var i:int = 0; i < inArr.length; i++ ) {
				_model.'.toCamelCaseMember($className).'s.refresh();
				var foundIndex:int = _model.'
					.toCamelCaseMember($className).'s
						.binarySearch( "'.$primaryKey.'" ,
								inArr[i].'.$primaryKey.');
				if (foundIndex >= 0 ) {
					_model.'.toCamelCaseMember($className).'s[foundIndex]
						.restore( inArr[i] );
				}
				else {
					_model.'
						.toCamelCaseMember($className).'s.addItem( inArr[i] );
';
		foreach( $columns as $key=>$columnassoc ) {
			if( ! is_int( $key ) ) {
				continue;
			}
			$fkeyname = toFKeyName( $columnassoc[0] );
			if( array_key_exists( 2, $columnassoc )
					&& $columnassoc[2]['constraint_type'] == 'FOREIGN KEY'
			 		&& $fkeyname ) {
				$export .=
'					'.toCamelCase($columnassoc[2]['referenced_table_name'])
						.'Command.addObjectsToModel(
						[ inArr[i].'.$fkeyname.' ] );
';
			}
			if( array_key_exists( 3, $columnassoc ) ) {
				foreach( $columnassoc[3] as $k2=>$referencer ) {
					$referencerTableName = $referencer['table_name'];
					$referencerTable = con::$tables
							[ $referencerTableName ] ;
					if( ! array_key_exists( 'isManyToMany', $referencerTable )
						|| $referencerTable['isManyToMany']
						){
						continue;
					}
					$refColName = toCamelCaseMember(
								$referencer['table_name'] );
					$export .=
'					'.toCamelCase($referencerTableName)
						.'Command.addObjectsToModel(
						inArr[i].'.$refColName.'s );
';
				}
			}
		}

		foreach( $refManyTables as $k=>$refManyColumn ) {
			if( ! is_int( $k ) ) {
				continue;
			}
			$refTableName =
				toCamelCaseMember(
						$refManyColumn['away_column'][2]
						['referenced_table_name']);
			$export .=
'					'.toCamelCase($refTableName)
						.'Command.addObjectsToModel(
						inArr[i].'.$refTableName.'s );
';
		}


		$export .=
'
				}
			}
		}


		// return functions
		private function onCountAll( event:ResultEvent ):void {
			_model.'.toCamelCaseMember($className).'Count = int(event.result);
			// if the view that dispatched Event implements
			//  IView then call update on Iview
			if(event.token.originator.data is IView)
				event.token.originator.data.update(event.token.originator,event);
		}

		private function onGetAll( event:ResultEvent ):void {
			var array:Array = ArrayUtil.toArray( event.result );
			/* for( var i:int = 0; i < array.length; i++ ) {
				_model.add(array[i]);
			} */
			//for( var i:int = 0; i < array.length; i++ ) {
			//	_model.'.toCamelCaseMember($className).'s.addItem( array[i] );
			//}
			addObjectsToModel( array );
			//_model.addArray( array );
			// if the view that dispatched Event implements
			//  IView then call update on Iview
			if(event.token.originator.data is IView)
				event.token.originator.data.update(event.token.originator,event);
		}

		private function onGetOne( event:ResultEvent ):void {
			/* for( var i:int = 0; i < array.length; i++ ) {
				_model.add(array[i]);
			} */
			//for( var i:int = 0; i < array.length; i++ ) {
			//	_model.'.toCamelCaseMember($className).'s.addItem( array[i] );
			//}
			addObjectsToModel( [event.result] );
			//_model.addArray( array );
			// if the view that dispatched Event implements
			//  IView then call update on Iview
			if(event.token.originator.data is IView)
				event.token.originator.data.update(event.token.originator,event);
		}

		private function onGetAllByStartLength( event:ResultEvent ):void {
			var array:Array = ArrayUtil.toArray( event.result );
			/* for( var i:int = 0; i < array.length; i++ ) {
				_model.add(array[i]);
			} */
			//for( var i:int = 0; i < array.length; i++ ) {
			//	_model.'.toCamelCaseMember($className).'s.addItem( array[i] );
			//}
			addObjectsToModel( array );
			//_model.addArray( array );
			// if the view that dispatched Event implements
			//  IView then call update on Iview
			if(event.token.originator.data is IView)
				event.token.originator.data.update(event.token.originator,event);
		}

		private function onCreateOne( event:ResultEvent ):void {
			//Alert.show( "createOneResult: " + event.result );
			if( event.result ) {
				//_model.'.toCamelCaseMember($className).'s.addItem( '
					.$className.'(event.result) );
				addObjectsToModel( [event.result] );
				// if the view that dispatched Event implements
				//  IView then call update on Iview
				if(event.token.originator.data is IView)
					event.token.originator.data.update(event.token.originator,event);
			}
			else {
				trace( "could not update properly" );
			}
		}
		private function onUpdateOne( event:ResultEvent ):void {
			//Alert.show( "createOneResult: " + event.result );
			if( event.result ) {
				//_model.'.toCamelCaseMember($className).'s.addItem( '
					.$className.'Event(
							//event.token.originator).paramItem );
				//_model.add( '.$className
					.'Event(event.token.originator).paramItem );
				addObjectsToModel( [ '.$className
					.'Event(event.token.originator).paramItem ] );
				// if the view that dispatched Event implements
				//  IView then call update on Iview
				if(event.token.originator.data is IView)
					event.token.originator.data.update(event.token.originator,event);
			}
			else {
				trace( "could not update properly" );
			}
		}
		private function onDeleteOne( event:ResultEvent ):void {
			//Alert.show( "createOneResult: " + event.result );
			if( event.result ) {
				//_model.remove( '.$className.'Event(event.token.originator).paramItem );
				_model.'.toCamelCaseMember($className).'s
					.removeItem( '.$className.'Event
						(event.token.originator).paramItem, "'
						.toCamelCaseMember($primaryKey).'");
				// if the view that dispatched Event implements
				//  IView then call update on Iview
				if(event.token.originator.data is IView)
					event.token.originator.data.update(event.token.originator,event);
			}
			else {
				trace( "could not delete properly" );
			}
		}

		/* private function onFault(event:FaultEvent):void
		{
			Alert.show(event.fault.message);
		} */
	}
}
';
	return $export;
}

?>
